#include		"ModuleCall.h"

ModuleCall::ModuleCall(Processor &proc) : _proc(proc)
{
	_operator[CALL] = &ModuleCall::call;
	_operator[ENDCALL] = &ModuleCall::endCall;
}

ModuleCall::~ModuleCall()
{

}

void									ModuleCall::takeOrder(IOrder *order, Protocol proto)
{
		std::cout << "received order" << std::endl;
	byte	op = *(byte*)order->getData(sizeof(byte));

	if (_operator.find((Operator) op) != _operator.end())
		(this->*_operator[(Operator) op])(order);
	delete order;
}

void									ModuleCall::call(IOrder *order)
{
	std::cout << "received call" << std::endl;
	unsigned int	senderId = order->getSenderId();
	unsigned int	receipId = *(unsigned int*)order->getData(sizeof(receipId));
	
	for (std::vector<Room *>::iterator it = _rooms.begin(); it != _rooms.end(); ++it)
	{
		if (((*it)->getSender() == receipId || (*it)->getReceive() == receipId) &&
			((*it)->getSender() != senderId && (*it)->getReceive() != senderId))
		{
			callDecline(senderId, receipId);
			return;
		}
	}
	for (std::vector<Room *>::iterator it = _rooms.begin(); it != _rooms.end(); ++it)
	{
		if ((*it)->getSender() == receipId && (*it)->getReceive() == senderId)
		{
			connectRequest(senderId, receipId);
			connectRequest(receipId, senderId);
			return;
		}
	}
	callRequest(senderId, receipId);
}

void									ModuleCall::callDecline(unsigned int senderId, unsigned int receipId)
{
	IOrder			*newOrder = new Order();
	Protocol		proto = Protocol::CALL;
	Operator		op = ENDCALL;

	newOrder->init();
	newOrder->pushData(&proto, sizeof(Protocol));
	newOrder->pushData(&op, sizeof(Operator));
	newOrder->pushData(&receipId, sizeof(receipId));
	_proc.sendOrder(newOrder, senderId);
}

void									ModuleCall::connectRequest(unsigned int senderId, unsigned int receipId)
{
	IOrder			*senderOrder = new Order();
	Protocol		proto = Protocol::CALL;
	Operator		op = CONNECT;

	senderOrder->init();
	senderOrder->pushData(&proto, sizeof(Protocol));
	senderOrder->pushData(&op, sizeof(Operator));
	senderOrder->pushData(&receipId, sizeof(receipId));
	_proc.sendOrder(senderOrder, senderId);
}

void									ModuleCall::callRequest(unsigned int senderId, unsigned int receipId)
{
	IOrder			*newOrder = new Order();
	Protocol		proto = Protocol::CALL;
	Operator		op = CALL;
	std::cout << "received call command from " << senderId << " to " << receipId << std::endl;

	newOrder->init();
	newOrder->pushData(&proto, sizeof(Protocol));
	newOrder->pushData(&op, sizeof(Operator));
	newOrder->pushData(&senderId, sizeof(senderId));
	_proc.sendOrder(newOrder, receipId);
	_rooms.push_back(new Room(senderId, receipId));
}

void									ModuleCall::endCall(IOrder *order)
{
	unsigned int	senderId = order->getSenderId();
	unsigned int	receipId = *(unsigned int*)order->getData(sizeof(receipId));

	std::cout << "SEND HANG UP !!!!!" << std::endl;
	callDecline(senderId, receipId);
	callDecline(receipId, senderId);
	for (std::vector<Room *>::iterator it = _rooms.begin(); it != _rooms.end(); ++it)
	{
		if (((*it)->getSender() == senderId && (*it)->getReceive() == receipId) ||
			((*it)->getSender() == receipId && (*it)->getReceive() == senderId))
		{
			std::cout << "erase room" << std::endl;
			delete (*it);
			_rooms.erase(it);
			return;
		}
	}
}

std::vector<Protocol>					ModuleCall::getProtocol() const
{
	return _proto;
}

void									ModuleCall::init()
{

}
